package com.zhuyuan.system.service.impl;

import com.zhuyuan.core.util.StringUtils;
import com.zhuyuan.database.base.BaseServiceImpl;
import com.zhuyuan.system.api.domain.SysMenu;
import com.zhuyuan.system.constant.UserConstants;
import com.zhuyuan.system.domain.vo.MetaVo;
import com.zhuyuan.system.domain.vo.RouterVo;
import com.zhuyuan.system.domain.vo.SysMenuVo;
import com.zhuyuan.system.mapper.SysMenuMapper;
import com.zhuyuan.system.mapper.SysRoleMapper;
import com.zhuyuan.system.service.ISysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 张琳凯
 * @Description: TODO
 * @DateTime: 2025/2/19 16:19
 **/
@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenu, SysMenuMapper> implements ISysMenuService {

    private final SysMenuMapper sysMenuMapper;
    private final SysRoleMapper sysRoleMapper;

    @Override
    public List<SysMenuVo> getALLMenuTree(SysMenu sysMenu) {
        List<SysMenu> sysMenus = sysMenuMapper.queryAllMenuList(sysMenu);
        return buildMenuTree(sysMenus);
    }

    @Override
    public List<String> getALLPerm() {
        return sysMenuMapper.queryAllPermList();
    }

    @Override
    public List<SysMenuVo> getMenuTreeByUid(SysMenu sysMenu, Long id) {
        //判断是否为admin,admin返回所有
        boolean isAdmin = sysRoleMapper.hasSuperAdminByUid(id);
        if (isAdmin) {
            return getALLMenuTree(new SysMenu());
        } else {
            sysMenu.getParams().put("userId", id);
            List<SysMenu> sysMenus = sysMenuMapper.queryMenuByUserId(sysMenu);
            return buildMenuTree(sysMenus);
        }
    }

    @Override
    public List<String> getPermTreeByUid(Long id) {
        //判断是否为admin,admin返回所有
        boolean isAdmin = sysRoleMapper.hasSuperAdminByUid(id);
        if (isAdmin) {
            return getALLPerm();
        } else {
            return sysMenuMapper.queryPermByUserId(id);
        }

    }

    @Override
    public List<RouterVo> getRouterTreeByUid(Long id) {
        SysMenu sysMenu = new SysMenu();
        sysMenu.setVisible("0");
        sysMenu.setStatus("0");
        List<SysMenuVo> menus = getMenuTreeByUid(sysMenu, id);
        return convertToRouterList(menus);
    }

    /**
     * 构建菜单树
     *
     * @param menuList 菜单列表
     * @return 包含子菜单的菜单树
     */
    private List<SysMenuVo> buildMenuTree(List<SysMenu> menuList) {
        // 先将 SysMenu 列表转换为 SysMenuVo 列表
        List<SysMenuVo> menuVoList = convertToMenuVoList(menuList);
        // 获取所有的根菜单（父菜单 ID 为 null 或 0 的菜单）
        List<SysMenuVo> rootMenus = menuVoList.stream()
                .filter(menu -> menu.getParentId() == null || menu.getParentId() == 0)
                .collect(Collectors.toList());
        // 递归构建菜单树
        for (SysMenuVo rootMenu : rootMenus) {
            buildChildMenus(rootMenu, menuVoList);
        }
        return rootMenus;
    }

    /**
     * 将 SysMenu 列表转换为 SysMenuVo 列表
     *
     * @param menuList 菜单列表
     * @return SysMenuVo 列表
     */
    private List<SysMenuVo> convertToMenuVoList(List<SysMenu> menuList) {
        List<SysMenuVo> menuVoList = new ArrayList<>();
        for (SysMenu menu : menuList) {
            SysMenuVo menuVo = new SysMenuVo();
            menuVo.setMenuId(menu.getMenuId());
            menuVo.setMenuName(menu.getMenuName());
            menuVo.setParentId(menu.getParentId());
            menuVo.setOrderNum(menu.getOrderNum());
            menuVo.setPath(menu.getPath());
            menuVo.setComponent(menu.getComponent());
            menuVo.setQuery(menu.getQuery());
            menuVo.setRouteName(menu.getRouteName());
            menuVo.setIsFrame(menu.getIsFrame());
            menuVo.setIsCache(menu.getIsCache());
            menuVo.setMenuType(menu.getMenuType());
            menuVo.setPerms(menu.getPerms());
            menuVo.setIcon(menu.getIcon());
            menuVo.setVisible(menu.getVisible());
            menuVoList.add(menuVo);
        }
        return menuVoList;
    }

    /**
     * 递归构建子菜单
     *
     * @param parentMenu 父菜单
     * @param menuVoList 菜单列表
     */
    private void buildChildMenus(SysMenuVo parentMenu, List<SysMenuVo> menuVoList) {
        List<SysMenuVo> childMenus = menuVoList.stream()
                .filter(menu ->
                        menu.getParentId() != null &&
                                menu.getParentId().equals(parentMenu.getMenuId()) &&
                                (menu.getMenuType().equals(UserConstants.TYPE_DIR) || menu.getMenuType().equals(UserConstants.TYPE_MENU)))
                .collect(Collectors.toList());
        parentMenu.setChildren(childMenus);
        for (SysMenuVo childMenu : childMenus) {
            buildChildMenus(childMenu, menuVoList);
        }
    }

    /**
     * 将 SysMenuVo 列表转换为 RouterVo 列表
     *
     * @param menuList SysMenuVo 列表
     * @return RouterVo 列表
     */
    private List<RouterVo> convertToRouterList(List<SysMenuVo> menuList) {
        List<RouterVo> routerList = new ArrayList<>();
        for (SysMenuVo menu : menuList) {
            RouterVo router = convertToRouter(menu);
            routerList.add(router);
        }
        return routerList;
    }

    /**
     * 将单个 SysMenuVo 对象转换为 RouterVo 对象
     *
     * @param menu SysMenuVo 对象
     * @return RouterVo 对象
     */
    private RouterVo convertToRouter(SysMenuVo menu) {
        RouterVo router = new RouterVo();
        // 设置路由名字
        router.setName(getRouteName(menu));
        // 设置路由地址
        router.setPath(getRoutePath(menu));
        router.setComponent(getComponent(menu));
        // 设置是否隐藏路由，这里假设显示状态为 1 时隐藏
        router.setHidden(UserConstants.NO_VISIABLE.equals(menu.getVisible()));
        // 设置重定向地址，这里没有重定向
        router.setRedirect(null);

        // 设置路由参数
        router.setQuery(menu.getQuery());
        // 设置 alwaysShow，这里假设如果有子菜单则 alwaysShow 为 true
        router.setAlwaysShow(menu.getChildren() != null && !menu.getChildren().isEmpty());

        // 设置 meta 信息
        MetaVo meta;
        if (menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath())) {
            //页面内打开外链，如http://www.baidu.com
            router.setPath("");
            router.setComponent(UserConstants.INNER_LINK);
            meta = new MetaVo(menu.getMenuName(), menu.getIcon(), UserConstants.NO_CACHE.equals(menu.getIsCache()), menu.getPath());
        } else if (menu.getIsFrame().equals(UserConstants.YES_FRAME) && StringUtils.ishttp(menu.getPath())) {
            //新标签页打开外链，如http://www.baidu.com
            // 设置组件地址
            meta = new MetaVo(menu.getMenuName(), menu.getIcon(), UserConstants.NO_CACHE.equals(menu.getIsCache()), null);
        } else {
            // 设置组件地址
            meta = new MetaVo(menu.getMenuName(), menu.getIcon(), UserConstants.NO_CACHE.equals(menu.getIsCache()), null);
        }
        router.setMeta(meta);

        // 递归处理子菜单
        if (menu.getChildren() != null && !menu.getChildren().isEmpty()) {
            List<RouterVo> children = convertToRouterList(menu.getChildren());
            router.setChildren(children);
        }

        return router;
    }

    /**
     * 获取路由名称，如没有配置路由名称则取路由地址
     */
    private String getRouteName(SysMenuVo sysMenu) {
        String name = StringUtils.isNotEmpty(sysMenu.getRouteName()) ? sysMenu.getRouteName() : sysMenu.getPath();
        return StringUtils.capitalize(name);
    }

    /**
     * 获取路由地址
     */
    private String getRoutePath(SysMenuVo sysMenu) {
        String path = sysMenu.getPath();
        if (sysMenu.getParentId() == 0 && sysMenu.getMenuType().equals(UserConstants.TYPE_DIR)) {
            //内部链接且为一级目录
            path = "/" + path;
        }
        return path;
    }

    /**
     * 获取组件信息
     */
    public String getComponent(SysMenuVo menu) {
        String component;
        if (StringUtils.isEmpty(menu.getComponent())) {
            component = UserConstants.LAYOUT;
        } else {
            component = menu.getComponent();
        }
        return component;
    }
}